#include "lj_ringbuffer.h"
#include "lj_ringbuffer_print.h"
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE 100
BUFFER_TYPE data[BUFFER_SIZE] = { 0 };
BUFFER_TYPE poll[] = {
    { 10, "" },
    { 11, "" },
    { 12, "" },
    { 13, "" },
    { 14, "" },
};

lj_ringbuffer_sync_t rbs;

#define TEST_COUNT 100
#define TEST_THD_PUSH_AMOUNT 2
#define TEST_THD_PULL_AMOUNT 2
#define TEST_SIZE (TEST_COUNT * TEST_THD_PUSH_AMOUNT)

void* push_buf(void* args)
{
    BUFFER_TYPE push[TEST_COUNT] = { 0 };

    pthread_t tid = pthread_self();
    printf("init thd prt=%p\n", &tid);
    for (int i = 0; i < TEST_COUNT; i++) {
        push[i].fd = i;
        sprintf(push[i].buff, "thd %p, i %d", &tid, i);
        lj_ring_buffer_sync_push(&rbs, &push[i], 1);
    }

    return NULL;
}

void* pull_buf(void* args)
{
    BUFFER_TYPE pull[TEST_SIZE] = { 0 };
    char str[50] = { 0 };
    pthread_t tid = pthread_self();
    printf("init thd prt=%p\n", &tid);
    for (size_t i = 0; i < TEST_COUNT; i++) {
        lj_ring_buffer_sync_pull(&rbs, &pull[i], 1);
    }
    sprintf(str, "pull@%p", &tid);
    print_buffer_sync(pull, TEST_SIZE, str);

    return NULL;
}

int main(int argc, char const* argv[])
{

    BUFFER_TYPE* pdata = data;
    pdata += 20;
    lj_ring_buffer_sync_init(&rbs, pdata, 50);

    pthread_t pushset[TEST_THD_PUSH_AMOUNT];
    for (size_t i = 0; i < TEST_THD_PUSH_AMOUNT; i++) {
        pthread_create(&pushset[i], NULL, push_buf, NULL);
    }

    pthread_t pullset[TEST_THD_PULL_AMOUNT];
    for (size_t i = 0; i < TEST_THD_PULL_AMOUNT; i++) {
        pthread_create(&pullset[i], NULL, pull_buf, NULL);
    }
    // print_sync_ringbuffer(rbs);

    void** tret = NULL;
    for (size_t i = 0; i < TEST_THD_PUSH_AMOUNT; i++) {
        pthread_join(pushset[i], tret);
    }

    for (size_t i = 0; i < TEST_THD_PULL_AMOUNT; i++) {
        pthread_join(pullset[i], tret);
    }

    print_sync_ringbuffer(rbs);
    // print_buffer(data, BUFFER_SIZE, "data");

    return 0;
}
